using System;
using System.Collections;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Text;
using System.Xml;
using System.IO;
using System.Text.RegularExpressions;

using WPS.Libraries.CssDom;

namespace WPS.Modules.StyleLibrary
{
	/// <summary>
	/// Page for editing Font styles (SPAN) in the Style Library.
	/// </summary>
	public partial class FontEdit : StyleLibraryBasePage
	{
		/// <summary>
		/// Patterns for searching Font styles the CSS file.
		/// </summary>
		private class RuleSelector
		{
			public const string Font = ".{0}, table tr td.{0}";
		}

		/// <summary>
		/// Stores font related class names from WYSIWYG.css parsed at page_load.
		/// </summary>
		protected StyleNameList ClassNames;

		#region Page events

		protected new void Page_Load(object sender, System.EventArgs e)
		{
			this.CmsIntegration = new StyleLibraryIntegration();

			// Initialize available class names list and renamed class names list.
			this.ClassNames = StyleSheetManager.LoadAllStyles(GetCssFilePath(false));

			if(Page.IsPostBack)
			{
				// Recreate NewStyle entry if creating new font style.
				if(Request.Form["hdnOriginalName"] == "NewStyle")
				{
					this.ClassNames.Fonts.Add("NewStyle");
				}
			}

			base.Page_Load(sender, e);
		}

		#endregion

		#region Overriding some standard StyleSheetBaseControl functions

		/// <summary>
		/// Load styles from WYSIWYG.css and add a new one.
		/// </summary>
		/// <param name="styleName">Which font class to find and load.</param>
		/// <param name="fromExamples">Load the examples CSS instead wysiwyg.css for copying style from.</param>
		protected override void LoadAsNew(string styleName, bool fromExamples)
		{
			CSSStyleSheet css = new CSSStyleSheet();
			if(css.Load(GetCssFilePath(fromExamples)))
			{
				// Add a NEW entry to Rules and Renames!
				this.ClassNames.Fonts.Add("NewStyle");
				this.OriginalName = "NewStyle";

				// Find all font styles
				StyleRuleSearch[] rules = GetRules(styleName);
				StyleSheetManager.SearchStyleRules(css, ref rules, true);
				//StyleSheetManager.RenameRules(ref rules, GetRenames(""));

				// Copy properties of the selected style to the appended "NewStyle" style.
				string origSelector = String.Format(RuleSelector.Font, styleName);
				for(int i = 0; i < rules.Length; i++)
				{
					if(rules[i].SelectorText == origSelector && rules[i].Rule != null)
					{
						// Copy css text to last rule (to NewStyle)
						CSSStyleRule rule = (CSSStyleRule)rules[i].Rule;
						CSSStyleRule lastRule = (CSSStyleRule)rules[rules.Length - 1].Rule;
						lastRule.style.cssText = rule.style.cssText;
						break;
					}
				}

				this.LoadedStylesJS = StyleSheetManager.CreateJSArray(rules);
			}
		}

		/// <summary>
		/// Delete the selected style's all rules. (Overridden to delete only ONE RULE.)
		/// </summary>
		/// <param name="styleName">Which style to delete.</param>
		protected override void DeleteStyle(string styleName)
		{
			string cssFileName = GetCssFilePath(false);
			CSSStyleSheet css = new CSSStyleSheet();

			if(css.Load(cssFileName))
			{
				// Create a rulesearch for only one of the rules.
				StyleRuleSearch[] rules = {
						new StyleRuleSearch(String.Format(RuleSelector.Font, styleName))
				};
				// Delete this single rule.
				StyleSheetManager.DeleteStyleRules(css, ref rules);
				css.Save(cssFileName);
			}
		}

		/// <summary>
		/// Create the Javascript array for new style. 
		/// (Fonts: Overridden to load existing styles even when making new.)
		/// </summary>
		/// <param name="styleName">New stlye's temporary name.</param>
		protected override void CreateStyle(string styleName)
		{
			CSSStyleSheet css = new CSSStyleSheet();
			css.Load(GetCssFilePath(false));

			// Add a NEW entry to Rules and Renames!
			this.ClassNames.Fonts.Add("NewStyle");

			// Find all font styles
			StyleRuleSearch[] rules = GetRules(styleName);
			//string[] renames = GetRenames("NewStyle");

			StyleSheetManager.SearchStyleRules(css, ref rules, true);
			//StyleSheetManager.RenameRules(ref rules, renames);

			this.LoadedStylesJS = StyleSheetManager.CreateJSArray(rules);

			this.OriginalName = "NewStyle"; // Select the new entry.
		}

		#endregion

		#region Form validation

		protected override bool ValidateForm()
		{
			// When editing style, Fonts GUI cannot rename so copy original name
			if(Request.Form["hdnOriginalName"] != "NewStyle")
			{
				this.NewName = this.OriginalName;
			}

			// Did not rename NewStyle
			if(this.NewName == "NewStyle")
			{
				SendPageMessage("{#stylelibrary_dlg.wrong_name}", true);
				return false;
			}
			else
			{
				return base.ValidateForm();
			}
		}

		#endregion

		#region StyleSheetBaseControl overrides.

		/// <summary>
		/// Returns an array of all already defined font style selectors.
		/// </summary>
		/// <param name="styleName">Style name to create search rules for. (IGNORED in this override)</param>
		/// <returns>StyleRuleSearch array with SelectorText values set for the required css rules.</returns>
		protected override StyleRuleSearch[] GetRules(string styleName)
		{
			StyleRuleSearch[] rules = new StyleRuleSearch[this.ClassNames.Fonts.Count];

			for(int i = 0; i < this.ClassNames.Fonts.Count; i++)
			{
				rules[i] = new StyleRuleSearch(String.Format(RuleSelector.Font, this.ClassNames.Fonts[i]));
			}

			return rules;
		}

		/// <summary>
		/// Return an array of selector strings with a new name.
		/// </summary>
		/// <param name="newName">New style name for selectors.</param>
		/// <returns>List of CSS selectors necessary for this style.</returns>
		protected override string[] GetRenames(string newName)
		{
			string[] renames = new string[this.ClassNames.Fonts.Count];

			for(int i = 0; i < this.ClassNames.Fonts.Count; i++)
			{
				// Replace NewStyle placeholder, keep other font style names
				if(this.ClassNames.Fonts[i] == "NewStyle")
				{
					renames[i] = String.Format(RuleSelector.Font, newName);
				}
				else
				{
					renames[i] = String.Format(RuleSelector.Font, this.ClassNames.Fonts[i]);
				}
			}

			return renames;
		}

		/// <summary>
		/// Send messages to pagemessagecontrol from the baseclass.
		/// </summary>
		/// <param name="message">Message text to display.</param>
		/// <param name="type">Message type error or text.</param>
		protected override void SendPageMessage(string message, bool error)
		{
			pgmPageMessage.Send(message, error);
		}
		#endregion

		#region Child control init

		protected void btnSave_Init(object sender, EventArgs e)
		{
			btnSave.Attributes.Add("onclick", "updateDemo(); return true;");
		}

		#endregion
	}
}
